package com.devfest.wishmaster;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Base64;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.Toast;

import com.devfest.wishmaster.gui.MyApplication;
import com.devfest.wishmaster.model.WishItem;
import com.devfest.wishmaster.model.WishList;

public class AddWishlistItemActivity extends Activity {

	private static final String TAG = "AddWishlistItemActivity";
	private EditText wishlistItemTitle, wishlistItemDescription,
			wishlistItemPrice;
	private WishList wishList;

	private Integer userId, wishlistId;
	private Spinner wishlistMode;
	private ImageView imageView;
	WishItem wishItem;

	private String newImagePath = "";
	private String url = "http://www.wishmaster.upwebsite.info/add-wish-list-api/";
	private SendWishItemTask sendWishItemTask;

	@SuppressWarnings("deprecation")
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setTitle("Make a wish");
		setContentView(R.layout.activity_add_wishlist_item);

		int wishListPosition = getIntent().getIntExtra("wish_list_position", 0);
		List<WishList> wishlists = MyApplication.getInstance().wishLists;
		wishList = wishlists.get(wishListPosition);

		// setUserId(wishList.getUser().getId());
		setWishlistId(wishList.getId());

		wishlistItemTitle = (EditText) findViewById(R.id.wishlistItemTitle);
		wishlistItemDescription = (EditText) findViewById(R.id.wishlistItemDescription);
		wishlistItemPrice = (EditText) findViewById(R.id.wishlistItemPrice);
		wishlistMode = (Spinner) findViewById(R.id.mode_spinner);
		imageView = (ImageView) findViewById(R.id.image);
		setValuesToMode();

		if (savedInstanceState != null) {
			newImagePath = savedInstanceState.getString("image_path");
			loadImage(newImagePath);
		}
		sendWishItemTask = (SendWishItemTask) getLastNonConfigurationInstance();
		if (sendWishItemTask != null) {
			sendWishItemTask.setActivity(this);
			sendWishItemTask.showLoading();
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.create_wish_menu, menu);
		return super.onCreateOptionsMenu(menu);
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.new_image:
			takeNewImage();
			break;
		case R.id.send:
			send();
			break;
		default:
			break;
		}
		return super.onOptionsItemSelected(item);
	}

	private void takeNewImage() {
		String extPicsDir = getExternalPicturesDir();
		if (extPicsDir == null) {
			Toast.makeText(this, "SD is not available, try later",
					Toast.LENGTH_LONG).show();
			return;
		}
		Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
		newImagePath = prepareImageFile(extPicsDir);
		intent.putExtra(MediaStore.EXTRA_OUTPUT,
				Uri.fromFile(new File(newImagePath)));
		startActivityForResult(intent, 17);
	}

	private String prepareImageFile(String dir) {
		SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US);
		String path = dir + "/image_" + df.format(new Date()) + ".jpg";
		File file = new File(path);
		try {
			if (!file.createNewFile()) {
				Log.w(TAG, "file: " + path
						+ " already exists, possibly overwriting old data");
			}
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
		return file.getAbsolutePath();
	}

	private String getExternalPicturesDir() {
		String storageState = Environment.getExternalStorageState();
		Log.v(TAG, "storage state: " + storageState);
		File dir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
		return dir == null ? null : dir.getAbsolutePath();
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		if (resultCode == RESULT_OK && requestCode == 17) {
			loadImage(newImagePath);
		}
	}

	private void loadImage(String imgPath) {
		if (imgPath != null) {
			imageView.setVisibility(View.VISIBLE);
			int sw = getScreenWidth();
			imageView.setImageBitmap(getScaledBitmap(imgPath, sw, sw));

		}
	}

	public Bitmap getScaledBitmap(String path, int width, int height) {
		BitmapFactory.Options opts = new BitmapFactory.Options();
		opts.inSampleSize = getSampleSize(path, width, height);
		return BitmapFactory.decodeFile(path, opts);
	}

	private int getSampleSize(String path, int dw, int dh) {
		BitmapFactory.Options opts = new BitmapFactory.Options();
		opts.inJustDecodeBounds = true;
		BitmapFactory.decodeFile(path, opts);
		int width = opts.outWidth;
		int height = opts.outHeight;
		return Math.min(width / dw, height / dh);
	}

	private int getScreenWidth() {
		return getResources().getDisplayMetrics().widthPixels;
	}

	@Override
	@Deprecated
	public Object onRetainNonConfigurationInstance() {
		return sendWishItemTask;
	}

	private void setValuesToMode() {
		// TODO Auto-generated method stub

		ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
				this, R.array.mode_array, android.R.layout.simple_spinner_item);
		// Specify the layout to use when the list of choices appears
		adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
		// Apply the adapter to the spinner
		wishlistMode.setAdapter(adapter);
	}

	private void send() {

		if (sendWishItemTask == null) {
			sendWishItemTask = new SendWishItemTask();
			sendWishItemTask.setActivity(this);
			sendWishItemTask.execute();
		}
		if (true)
			return;

		if (wishlistItemTitle.getText().toString().trim().equals("")) {
			Toast.makeText(this, "Fill title", Toast.LENGTH_SHORT).show();
			return;
		}

		if (wishlistItemDescription.getText().toString().trim().equals("")) {
			Toast.makeText(this, "Fill description", Toast.LENGTH_SHORT).show();
			return;
		}

		if (wishlistItemPrice.getText().toString().trim().equals("")) {
			Toast.makeText(this, "Fill Price", Toast.LENGTH_SHORT).show();
			return;
		}

		final List<NameValuePair> params = new ArrayList<NameValuePair>();

		params.add(new BasicNameValuePair("userId", String.valueOf(userId)));
		params.add(new BasicNameValuePair("wishlistId", String
				.valueOf(wishlistId)));

		params.add(new BasicNameValuePair("title", wishlistItemTitle.getText()
				.toString().trim()));

		params.add(new BasicNameValuePair("description",
				wishlistItemDescription.getText().toString().trim()));

		params.add(new BasicNameValuePair("price", wishlistItemPrice.getText()
				.toString().trim()));

		params.add(new BasicNameValuePair("dateCreated", new Date().toString()));

		params.add(new BasicNameValuePair("mode", (String) wishlistMode
				.getSelectedItem()));
	}

	public Integer getUserId() {
		return userId;
	}

	public void setUserId(Integer userId) {
		this.userId = userId;
	}

	public Integer getWishlistId() {
		return wishlistId;
	}

	public void setWishlistId(Integer wishlistId) {
		this.wishlistId = wishlistId;
	}

	@Override
	public void onBackPressed() {
		if (sendWishItemTask != null) {
			sendWishItemTask.cancel(true);
		} else {
			super.onBackPressed();
		}
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		if (sendWishItemTask != null) {
			sendWishItemTask.dismissLoading();
			sendWishItemTask = null;
		}
	}

	@Override
	protected void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
		outState.putString("image_path", newImagePath);
	}

	static class SendWishItemTask extends AsyncTask<Void, Void, Boolean> {

		private ProgressDialog pd;

		private AddWishlistItemActivity activity;

		private HttpURLConnection conn;
		private OutputStream out;
		
		public void setActivity(AddWishlistItemActivity activity) {
			this.activity = activity;
		}

		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			showLoading();
		}

		private void showLoading() {
			if (pd != null && pd.isShowing()) {
				return;
			}
			pd = ProgressDialog.show(activity, "Sending", "Please wait");
		}

		@Override
		protected Boolean doInBackground(Void... arg0) {
			return makePost();
//			return makeGet();
		}

		private Boolean makeGet() {
			try {
				byte[] img = readImageAsByteArray();
				String content = "nm=gia&desc=desc"; 
//				+ &img=" + Base64.encodeToString(img, Base64.DEFAULT);
				String url = activity.url + "&" + content; 
				
				conn = (HttpURLConnection) new URL(url).openConnection();
				conn.setDoOutput(true);
				conn.setRequestMethod("GET");
//				conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
//				conn.setRequestProperty("charset", "utf-8");

//				out = conn.getOutputStream();
//				out.write(content.getBytes("UTF-8"));
//				out.flush();
				int responseCode = conn.getResponseCode();
				String responseMessage = conn.getResponseMessage();
				Log.v("CommitWishItemTask", "Response Code=" + responseCode + " ResponseMessage=" + responseMessage);
//				out.close();
				if (responseCode / 100 != 2) {
					throw new Exception();
				}
			} catch (Exception e) {
				Log.e("CommitWishItemTask", "Error while commiting wishitem", e);
				return false;
			} finally {
				if (conn != null) {
					conn.disconnect();
				}
			}
			return true;
		}
		
		@SuppressWarnings("deprecation")
		private Boolean makePost() {
			try {
				byte[] img = readImageAsByteArray();
				String base64Img = Base64.encodeToString(img, Base64.DEFAULT);
				String content = "nm=gia&desc=desc"
				+ "&img=" + base64Img;

				byte[] contentBytes = content.getBytes("UTF-8");
				
				conn = (HttpURLConnection) new URL(activity.url).openConnection();
				conn.setDoOutput(true);
				conn.setRequestMethod("POST");
				conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
				conn.setRequestProperty("Content-Length", "" + contentBytes.length);

				out = conn.getOutputStream();
				out.write(contentBytes);
				out.flush();
				int responseCode = conn.getResponseCode();
				String responseMessage = conn.getResponseMessage();
				Log.v("CommitWishItemTask", "Response Code=" + responseCode + " ResponseMessage=" + responseMessage);
				out.close();
				if (responseCode / 100 != 2) {
					throw new Exception();
				}
			} catch (Exception e) {
				Log.e("CommitWishItemTask", "Error while commiting wishitem", e);
				return false;
			} finally {
				if (conn != null) {
					conn.disconnect();
				}
			}
			return true;
		}

		private byte[] readImageAsByteArray() throws IOException {
			Bitmap bmp = activity.getScaledBitmap(activity.newImagePath, 100, 50);
			ByteArrayOutputStream bos = new ByteArrayOutputStream();
			if (bmp != null) {
				bmp.compress(CompressFormat.PNG, 100, bos);
				return bos.toByteArray();
			}
			return null;
		}

		private BufferedReader getReader() throws IOException {
			return new BufferedReader(new InputStreamReader(
					new FileInputStream(activity.newImagePath)));
		}

		@Override
		protected void onPostExecute(Boolean success) {
			super.onPostExecute(success);
			dismissLoading();
			if (success) {
				Toast.makeText(activity, "Succesfully commited",
						Toast.LENGTH_SHORT).show();
			} else {
				Toast.makeText(activity, "Commit failed", Toast.LENGTH_SHORT)
						.show();
			}
			activity.sendWishItemTask = null;
		}

		@Override
		protected void onCancelled() {
			super.onCancelled();
			if (conn != null) {
				conn.disconnect();
			}
			if (out != null) {
				try {
					out.close();
				} catch (IOException e) {
					Log.w(TAG, "error while closing stream", e);
				}
			}
			dismissLoading();
			activity.sendWishItemTask = null;
		}

		private void dismissLoading() {
			if (pd != null) {
				pd.dismiss();
				pd = null;
			}
		}
	}

}
